package br.com.caiocarrara.goodbuy.controller;

import static br.com.caelum.vraptor.view.Results.json;

import java.util.Collections;
import java.util.List;

import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.Validations;
import br.com.caiocarrara.goodbuy.dao.ProductDao;
import br.com.caiocarrara.goodbuy.interceptor.Restrict;
import br.com.caiocarrara.goodbuy.model.Product;

@Resource
public class ProductsController {

	private final Result result;
	private final Validator validator;
	private final ProductDao productDao;

	public ProductsController(ProductDao productDao, Result result,
			Validator validator) {
		this.result = result;
		this.validator = validator;
		this.productDao = productDao;
	}

	@Get("/products")
	public List<Product> list() {
		List<Product> result = productDao.listAll();
		Collections.sort(result);
		return result;
	}

	// PAGE RETURNS
	@Get("/products/new")
	@Restrict
	public void addForm() {
		
	}

	@Get("/products/{id}")
	@Restrict
	public Product editForm(Long id) {
		return productDao.getById(id);
	}

	// CRUD ACTIONS
	@Post("/products")
	@Restrict
	public void add(final Product product) {

		this.validate(product);
		validator.onErrorUsePageOf(this).addForm();

		this.productDao.save(product);
		result.redirectTo(this).list();
	}

	@Put("/products/{product.id}")
	@Restrict
	public void update(Product product) {
		this.validate(product);
		validator.onErrorUsePageOf(this).editForm(product.getId());
		productDao.update(product);
		result.redirectTo(this).list();
	}

	@Delete("/products/{id}")
	@Restrict
	public void delete(Long id) {
		productDao.delete(productDao.getById(id));
		result.redirectTo(this).list();
	}
	
	public List<Product> search(String name) {
		result.include("name", name);
		return productDao.search(name);
	}

	//KEEP IN MIND Representation VRaptor
	@Get("/products/search.json")
	public void searchJson(String q) {
		result.use(json()).withoutRoot()
			.from(productDao.search(q))
			.exclude("id", "description")
			.serialize();
	}

	private void validate(final Product product) {
		validator.checking(new Validations() {
			{

				that(product.getName() != null
						&& product.getName().length() >= 3, "product.name",
						"name.required");

				that(product.getDescription() != null
						&& product.getDescription().length() >= 40,
						"product.description", "description.required");

				that(product.getPrice() != null && product.getPrice() > 0.0,
						"product.price", "price.required");

			}
		});
	}
}
